package com.iakuil.app.common.tp;

import com.iakuil.app.common.core.constant.SysConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.util.ErrorHandler;

/**
 * 公共Spring Task配置
 *
 * <p>分布式场景建议推荐使用XXL-JOB
 *
 * @author Kai
 */
@Slf4j
@AutoConfiguration
@EnableScheduling
@ConditionalOnProperty(prefix = SysConstant.APP_SYMBOL + ".scheduling", name = "enabled", havingValue = "true")
public class ScheduleAutoConfiguration implements SchedulingConfigurer {

    private static final int THREAD_POOL_SIZE = 10;
    private static final int AWAIT_SECONDS = 60;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(schedulerExecutor());
    }

    /**
     * 定时任务任务线程池
     */
    public ThreadPoolTaskScheduler schedulerExecutor() {
        log.info("注意：定时任务线程池已启动！");
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(THREAD_POOL_SIZE);
        scheduler.setThreadNamePrefix("SchedulingTask-");
        scheduler.setAwaitTerminationSeconds(AWAIT_SECONDS);
        scheduler.setErrorHandler(new ScheduleErrorHandler());
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        scheduler.initialize();
        return scheduler;
    }

    private static class ScheduleErrorHandler implements ErrorHandler {
        private ScheduleErrorHandler() {
        }

        public void handleError(Throwable throwable) {
            log.error("Error calling ThreadPoolTaskScheduler", throwable);
        }
    }
}
